`include"defines.v"

module clint(

    input                   clk,
    input                   rst,

    input                   clint_rd_i,
    input                   clint_wr_i,
    input                   mtime_ena_i,
    input                   mtimecmp_ena_i,
    input      [`RAM_WIDTH] mem_data_write_i,
    input      [1:0]        mem_size_i,

    output reg [`REG_WIDTH] mtime_o,
    output reg [`REG_WIDTH] mtimecmp_o,
    output                  clint_interrupt_o

);

   always @(posedge clk)
    begin
        if( rst == `RST )begin
            mtime_o    <= 0;
            mtimecmp_o <= 0;
        end
        else if(clint_wr_i & mtime_ena_i)begin
            case(mem_size_i)
                `SIZE_B : begin mtime_o    <= 64'hffff &mem_data_write_i;
                                mtimecmp_o <= mtimecmp_o;
                                end
                `SIZE_H : begin mtime_o    <= 64'hfffffff &mem_data_write_i;
                                mtimecmp_o <= mtimecmp_o;
                                end
                `SIZE_W : begin mtime_o    <= 64'hffff_ffffffff &mem_data_write_i;
                                mtimecmp_o <= mtimecmp_o;
                                end
                `SIZE_D : begin mtime_o    <= 64'hffffffff_ffffffff &mem_data_write_i;
                                mtimecmp_o <= mtimecmp_o;
                                end
                default : begin mtime_o    <= mtime_o;
                                mtimecmp_o <= mtimecmp_o;
                                end
            endcase
        end 
        else if(clint_wr_i & mtimecmp_ena_i)begin
            case(mem_size_i)
                `SIZE_B : begin mtime_o    <= mtime_o;
                                mtimecmp_o <= 64'hffff & mem_data_write_i;
                                end
                `SIZE_H : begin mtime_o    <= mtime_o;
                                mtimecmp_o <= 64'hffffffff & mem_data_write_i;
                                end
                `SIZE_W : begin mtime_o    <= mtime_o;
                                mtimecmp_o <= 64'hffff_ffffffff & mem_data_write_i;
                                end
                `SIZE_D : begin mtime_o    <= mtime_o;
                                mtimecmp_o <= 64'hffffffff_ffffffff & mem_data_write_i;
                                end
                default : begin mtime_o    <= mtime_o;
                                mtimecmp_o <= mtimecmp_o;
                                end
            endcase
        end 
        else begin
            mtime_o    <= mtime_o + 1;
            mtimecmp_o <= mtimecmp_o;
        end
    end

    assign clint_interrupt_o = mtime_o >= mtimecmp_o;

    


endmodule